%%%-------------------------------------------------------------------
%%% @author mirahs(2892727493@qq.com)
%%% @doc
%%%     角色数据管理
%%% @end
%%%-------------------------------------------------------------------
-module(role_dao).

-export([
    fetch_base/2
    ,fetch_role/2

    ,create_role/6
    ,load_role/1
    ,save_role/1
    ,login_save_base/1
    ,add_role_by_file/1
]).

-include("common.hrl").
-include("role.hrl").
-include("role_data.hrl").


create_role(Rid, Sid, Account, Name, Sex, RegIp) ->
    RoleBase = #role_base{rid = Rid, sid = Sid, account = Account, name = Name, sex = Sex, lev = 1, reg_time = util_time:unixtime(), reg_ip = RegIp},
    RoleExt = role_ext_parse:init_role_ext(),
    RoleData = #role_data{rid = Rid, base = RoleBase, ext = RoleExt},

    case db_mnesia:write(role_data, RoleData) of
        {ok, _} ->
            {ok, _} = db_mnesia:write(role_base, RoleBase),
            ok;
        {error, Reason} ->
            ?ERR("创建角色失败: ~w", [Reason]),
            {error, err_role_create}
    end.

%% @spec load_role(Rid, SrvId) -> {ok, Role} | {false, Reason}
%% Rid = integer() 角色rid
%% SrvId = integer() 角色srv_id
%% Role = #role{} 角色
%% Reason = bitstring() 错误提示信息
%% 加载角色， 并做初始化
load_role(Rid) ->
    fetch_role(by_id, Rid).

%% @spec save(Role) -> ok | {false, Reason}
%% Role = #role{}
%% reason = bitstring()
%% 保存角色数据
%%save_role(Role = #role{id = RoleId, attr = #attr{fight_capacity = Fc}, pos = #pos{map_base_id = MBaseId, x = X, y = Y}, day_online = DayOnline}) ->
save_role(Role = #role{rid = Rid}) ->
    SaveTime = util_time:unixtime(),
    case role_parse:to_role_data(Role) of
        {ok, RoleData = #role_data{base = RoleBase0}} ->
            RoleBase = RoleBase0#role_base{save_time = SaveTime},
            case db_mnesia:write(role_data, RoleData#role_data{base = RoleBase}) of
                {ok, _} ->
                    case db_mnesia:write(role_base, RoleBase) of
                        {ok, _} ->
                            ignore;
                        {error, Reason} ->
                            ?ERR("保存角色基础数据出错: id=~w, reason=~s", [Rid, Reason]),
                            ignore
                    end,
                    ok;
                {error, Reason} ->
                    ?ERR("保存角色数据出错: id=~w, reason=~s", [Rid, Reason]),
                    {false, Reason}
            end;
        {false, Reason} ->
            ?ERR("保存角色数据出错: id=~w, reason=~s", [Rid, Reason]),
            {false, Reason}
    end.

%% @spec login_save_base(Role) -> ok | {false, Reason}
%% Role = #role{}
%% reason = bitstring()
%% 保存角色数据的role_base
login_save_base(Role = #role{rid = Rid}) ->
    {ok, #role_data{base = RoleBase}} = role_parse:to_role_data(Role),
    case db_mnesia:write(role_base, RoleBase) of
        {ok, _} -> ignore;
        {error, Reason} ->
            ?ERR("保存角色基础数据出错:id=~w,reason=~w", [Rid, Reason])
    end,
    ok.

fetch_role(by_id, Rid) ->
    case db_mnesia:read(role_data, Rid) of
        {ok, []} ->
            ?ERR("没有找到角色数据:~w", [Rid]),
            {false, err_role_fetch};
        {ok, [RoleData]} ->
            case role_parse:to_role(RoleData) of
                {ok, Role} -> {ok, Role};
                {false, Reason} ->
                    ?ERR("角色数据解析出错: id=~w, reason=~w", [Reason]),
                    {false, err_role_fetch}
            end;
        {ok, L} when is_list(L) ->
            ?ERR("角色数据数量不对: id=~w, size=~w", [Rid, length(L)]),
            {false, err_role_fetch};
        {error, Reason} ->
            ?ERR("加载角色数据出错: id=~w, reason=~w", [Rid, Reason]),
            {false, err_role_fetch}
    end.

%% @spec fetch_base(Type, Key) -> {ok, L} | {false, Reason}
%% Type = by_id | by_name | by_account
%% Key = term()
%% L = [#role_base{} | ..]
%% Reason = term()
%% 根据指定类型，读取角色基础数据
fetch_base(by_id, {Rid, SrvId}) ->
    case db_mnesia:read(role_base, {Rid, SrvId}) of
        {ok, L} -> {ok, L};
        {error, Reason} -> {false, Reason}
    end;
fetch_base(by_name, Name) ->
    case db_mnesia:read(role_base, #role_base.name, Name) of
        {ok, L} -> {ok, L};
        {error, Reason} -> {false, Reason}
    end;
fetch_base(by_account, {Account, Sid}) ->
    case db_mnesia:select(role_base, #role_base{account = Account, sid = Sid, _ = '_'}) of
        {ok, L} -> {ok, L};
        {error, Reason} -> {false, Reason}
    end;
fetch_base(by_account, Account) ->
    case db_mnesia:read(role_base, #role_base.account, Account) of
        {ok, L} -> {ok, L};
        {error, Reason} -> {false, Reason}
    end.

%% 增加误删的玩家数据
add_role_by_file(FileName) ->
    Path = lists:concat(["../var/", FileName, ".txt"]),
    case filelib:is_file(Path) of
        false -> ?INFO("~s 不存在", [Path]);
        true ->
            case file:consult(Path) of
                {error, Reason} -> ?INFO("读取文件 ~s 失败：~w", [Reason]);
                {ok, RoleDatas} ->
                    Fun = fun(RoleData) ->
                        case db_mnesia:read(role_data, RoleData#role_data.rid) of
                            {ok, [_ | _]} ->
                                ?INFO("角色 ~s 已存在", [RoleData#role_data.rid]);
                            _ ->
                                case db_mnesia:write(role_data, RoleData) of
                                    {ok, _} ->
                                        %?INFO("增加角色 ~s 成功", [RoleData#role_data.id]);
                                        ignore;
                                    {error, Reason} ->
                                        ?INFO("增加角色 ~s 失败：~w", [RoleData#role_data.rid, Reason])
                                end
                        end
                          end,
                    lists:foreach(Fun, RoleDatas)
            end
    end.
